/**
 * mouseInteractionService.js
 * 提供医学影像查看器的鼠标交互处理功能
 * 从ViewerPage.vue中提取，专注于鼠标拖拽、滚动等交互
 */

import * as viewportService from './viewportService';
import * as cornerstoneService from './cornerstoneService';
import cornerstone from 'cornerstone-core';

// 交互状态
const interactionState = {
  isLeftMouseDown: false,
  isRightMouseDown: false,
  isScrolling: false,
  lastMousePosition: { x: 0, y: 0 },
  lastMouseY: 0,
  scrollStartPosition: { y: 0, imageIndex: 0 },
  scrollSensitivity: 2, // 滚动灵敏度
};

/**
 * 处理鼠标按下事件
 * @param {MouseEvent} event - 鼠标事件
 * @param {Object} data - 包含viewportElement和当前状态的对象
 * @returns {Object} 更新后的交互状态
 */
export function handleMouseDown(event, data) {
  const { viewportElement } = data;
  
  // 左键用于滚动
  if (event.button === 0) {
    event.preventDefault();
    interactionState.isLeftMouseDown = true;
    interactionState.lastMouseY = event.clientY;
    
    // 添加滚动状态样式
    if (viewportElement) {
      viewportElement.classList.add('scrolling');
    }
  }
  
  // 中键（滚轮点击）用于滚动
  else if (event.button === 1) {
    event.preventDefault();
    interactionState.isScrolling = true;
    interactionState.scrollStartPosition = {
      y: event.clientY,
      imageIndex: data.currentImageIndex || 0
    };
    
    if (viewportElement) {
      viewportElement.classList.add('scrolling');
    }
  }
  
  // 右键用于缩放
  else if (event.button === 2) {
    event.preventDefault();
    interactionState.isRightMouseDown = true;
    interactionState.lastMousePosition = { x: event.clientX, y: event.clientY };
  }
  
  return { ...interactionState };
}

/**
 * 处理鼠标释放事件
 * @param {MouseEvent} event - 鼠标事件
 * @param {Object} data - 包含viewportElement的对象
 * @returns {Object} 更新后的交互状态
 */
export function handleMouseUp(event, data) {
  const { viewportElement } = data;
  
  // 结束左键滚动状态
  if (interactionState.isLeftMouseDown) {
    interactionState.isLeftMouseDown = false;
    if (viewportElement) {
      viewportElement.classList.remove('scrolling');
    }
  }
  
  // 结束中键滚动状态
  if (interactionState.isScrolling) {
    interactionState.isScrolling = false;
    if (viewportElement) {
      viewportElement.classList.remove('scrolling');
    }
  }
  
  // 结束右键缩放状态
  if (interactionState.isRightMouseDown) {
    interactionState.isRightMouseDown = false;
  }
  
  return { ...interactionState };
}

/**
 * 处理鼠标移动事件
 * @param {MouseEvent} event - 鼠标事件
 * @param {Object} data - 包含viewportElement和当前状态的对象
 * @param {Function} onImageChange - 图像改变时的回调函数
 * @returns {Object} 包含状态和变更的对象
 */
export function handleMouseMove(event, data, onImageChange) {
  const { viewportElement, currentImageIndex, totalImages } = data;
  let result = {
    changes: {
      imageIndex: currentImageIndex,
      zoomChanged: false
    },
    state: { ...interactionState }
  };
  
  // 处理左键滚动
  if (interactionState.isLeftMouseDown && totalImages > 1) {
    const deltaY = interactionState.lastMouseY - event.clientY;
    const scrollAmount = Math.round(deltaY * interactionState.scrollSensitivity);
    
    if (scrollAmount !== 0) {
      const newIndex = Math.max(0, Math.min(totalImages - 1, currentImageIndex + scrollAmount));
      if (newIndex !== currentImageIndex) {
        result.changes.imageIndex = newIndex;
        
        // 调用回调函数
        if (onImageChange) {
          onImageChange(newIndex);
        }
      }
    }
    
    interactionState.lastMouseY = event.clientY;
  }
  
  // 处理中键滚动
  else if (interactionState.isScrolling && totalImages > 1) {
    const deltaY = interactionState.scrollStartPosition.y - event.clientY;
    const viewportHeight = viewportElement ? viewportElement.clientHeight : 500;
    const indexChange = Math.round((deltaY / viewportHeight) * totalImages);
    let newIndex = interactionState.scrollStartPosition.imageIndex + indexChange;
    newIndex = Math.max(0, Math.min(totalImages - 1, newIndex));
    
    if (newIndex !== currentImageIndex) {
      result.changes.imageIndex = newIndex;
      
      // 调用回调函数
      if (onImageChange) {
        onImageChange(newIndex);
      }
    }
  }
  
  // 处理右键缩放
  else if (interactionState.isRightMouseDown && viewportElement) {
    const deltaY = event.clientY - interactionState.lastMousePosition.y;
    const scaleFactor = 1.0 - (deltaY * 0.01);
    
    // 应用缩放
    const zoomResult = applyZoom(viewportElement, scaleFactor);
    if (zoomResult.success) {
      result.changes.zoomChanged = true;
      result.changes.zoomLevel = zoomResult.scale;
    }
    
    interactionState.lastMousePosition = { x: event.clientX, y: event.clientY };
  }
  
  return result;
}

/**
 * 处理鼠标离开事件
 * @param {MouseEvent} event - 鼠标事件
 * @param {Object} data - 包含viewportElement的对象
 * @returns {Object} 更新后的交互状态
 */
export function handleMouseLeave(event, data) {
  const { viewportElement } = data;
  
  // 重置所有状态
  interactionState.isLeftMouseDown = false;
  interactionState.isScrolling = false;
  interactionState.isRightMouseDown = false;
  
  if (viewportElement) {
    viewportElement.classList.remove('scrolling');
  }
  
  return { ...interactionState };
}

/**
 * 处理鼠标滚轮事件
 * @param {WheelEvent} event - 滚轮事件
 * @param {Object} data - 包含当前状态的对象
 * @param {Function} onImageChange - 图像改变时的回调函数
 * @returns {Object} 包含状态和变更的对象
 */
export function handleMouseWheel(event, data, onImageChange) {
  event.preventDefault();
  
  const { currentImageIndex, totalImages } = data;
  let result = {
    changes: {
      imageIndex: currentImageIndex
    },
    state: { ...interactionState }
  };
  
  // 确定滚动方向
  const delta = Math.max(-1, Math.min(1, (event.wheelDelta || -event.detail)));
  
  // 计算新的索引
  let newIndex = currentImageIndex;
  if (delta < 0) {
    newIndex = Math.min(totalImages - 1, newIndex + 1);
  } else {
    newIndex = Math.max(0, newIndex - 1);
  }
  
  // 如果索引变化了，更新结果
  if (newIndex !== currentImageIndex) {
    result.changes.imageIndex = newIndex;
    
    // 调用回调函数
    if (onImageChange) {
      onImageChange(newIndex);
    }
  }
  
  return result;
}

/**
 * 应用缩放
 * @param {HTMLElement} viewportElement - 视口元素
 * @param {number} scaleFactor - 缩放因子
 * @returns {Object} 结果对象
 */
export function applyZoom(viewportElement, scaleFactor) {
  try {
    if (!viewportElement) return { success: false, error: '视口元素未定义' };
    
    // 获取当前视口
    const viewport = cornerstone.getViewport(viewportElement);
    
    // 应用缩放
    viewport.scale *= scaleFactor;
    
    // 限制缩放范围
    viewport.scale = Math.max(0.1, Math.min(10.0, viewport.scale));
    
    // 更新视口
    cornerstone.setViewport(viewportElement, viewport);
    
    return {
      success: true,
      scale: viewport.scale
    };
  } catch (error) {
    console.error('应用缩放失败:', error);
    return {
      success: false,
      error: error.message || '应用缩放失败'
    };
  }
}

/**
 * 处理全局鼠标按下事件
 * @param {MouseEvent} event - 鼠标事件
 * @param {HTMLElement} viewportElement - 视口元素
 * @returns {Object} 更新后的交互状态
 */
export function handleGlobalMouseDown(event, viewportElement) {
  if (event.button === 2 && viewportElement && viewportElement.contains(event.target)) {
    interactionState.isRightMouseDown = true;
    interactionState.lastMousePosition = { x: event.clientX, y: event.clientY };
    
    // 添加鼠标样式
    document.body.classList.add('zooming');
  }
  
  return { ...interactionState };
}

/**
 * 处理全局鼠标释放事件
 * @param {MouseEvent} event - 鼠标事件
 * @returns {Object} 更新后的交互状态
 */
export function handleGlobalMouseUp(event) {
  if (event.button === 2) {
    interactionState.isRightMouseDown = false;
    
    // 移除鼠标样式
    document.body.classList.remove('zooming');
  }
  
  return { ...interactionState };
}

/**
 * 处理全局鼠标移动事件
 * @param {MouseEvent} event - 鼠标事件
 * @param {Object} data - 包含viewportElement的对象
 * @param {Function} onZoomChange - 缩放变化时的回调函数
 * @returns {Object} 包含状态和变更的对象
 */
export function handleGlobalMouseMove(event, data, onZoomChange) {
  const { viewportElement } = data;
  let result = {
    changes: {
      zoomChanged: false
    },
    state: { ...interactionState }
  };
  
  if (interactionState.isRightMouseDown && viewportElement) {
    const deltaY = event.clientY - interactionState.lastMousePosition.y;
    
    // 计算缩放因子 (向上移动放大，向下移动缩小)
    const scaleFactor = 1.0 - (deltaY * 0.01);
    
    // 应用缩放
    const zoomResult = applyZoom(viewportElement, scaleFactor);
    if (zoomResult.success) {
      result.changes.zoomChanged = true;
      result.changes.zoomLevel = zoomResult.scale;
      
      // 调用回调函数
      if (onZoomChange) {
        onZoomChange(zoomResult.scale);
      }
    }
    
    // 更新鼠标位置
    interactionState.lastMousePosition = { x: event.clientX, y: event.clientY };
  }
  
  return result;
}

/**
 * 设置滚动灵敏度
 * @param {number} sensitivity - 灵敏度值
 */
export function setScrollSensitivity(sensitivity) {
  interactionState.scrollSensitivity = sensitivity;
}

/**
 * 获取当前交互状态
 * @returns {Object} 当前交互状态
 */
export function getInteractionState() {
  return { ...interactionState };
}

/**
 * 重置交互状态
 * @returns {Object} 重置后的交互状态
 */
export function resetInteractionState() {
  interactionState.isLeftMouseDown = false;
  interactionState.isRightMouseDown = false;
  interactionState.isScrolling = false;
  interactionState.lastMousePosition = { x: 0, y: 0 };
  interactionState.lastMouseY = 0;
  interactionState.scrollStartPosition = { y: 0, imageIndex: 0 };
  
  return { ...interactionState };
}

export default {
  handleMouseDown,
  handleMouseUp,
  handleMouseMove,
  handleMouseLeave,
  handleMouseWheel,
  handleGlobalMouseDown,
  handleGlobalMouseUp,
  handleGlobalMouseMove,
  applyZoom,
  setScrollSensitivity,
  getInteractionState,
  resetInteractionState
} 